import { createCellPos } from "../Tools/index";
import { refreshAllTagFormulasAPI, refreshPolymericColumnFormulaAPI, refreshPolymericRowFormulaAPI, } from "../api/DesignTableApi";
const startOffset = 0;
export default class FormulaService {
    context;
    constructor(context) {
        this.context = context;
    }
    get headerService() {
        return this.context.headerService;
    }
    get hot() {
        return this.context.hot;
    }
    get hyper() {
        return this.context.hyper;
    }
    get gridService() {
        return this.context.gridService;
    }
    destroy() {
        this.context = null;
    }
    /**
     * 刷新所有公式: 走后端接口
     * isContextData 如果为 true  getCpasTableGrid 取数通过 context.data取
     */
    async refreshAllPolymeric(isContextData = false) {
        let sourceData;
        if (isContextData) {
            sourceData = this.context.getCpasTableGrid(null, true);
        }
        else {
            sourceData = this.context.getCpasTableGrid();
        }
        try {
            const res = await refreshAllTagFormulasAPI(sourceData);
            if (res?.data) {
                return await this.context.reloadTable(res?.data, null, null, true);
            }
        }
        catch (e) {
            throw e;
        }
    }
    /**
     * 刷新聚合列的公式: 走后端接口
     */
    async getRefreshPolymericColumnFormula(cols, data) {
        let sourceData = this.context.getCpasTableGrid();
        if (data) {
            sourceData["data"] = data;
        }
        try {
            const res = await refreshPolymericColumnFormulaAPI(cols, sourceData);
            if (res?.data) {
                return await this.context.reloadTable(res?.data, null, null, true);
            }
        }
        catch (e) {
            throw e;
        }
    }
    /**
     * 刷新聚合行的公式： 走后端接口
     */
    async getRefreshPolymericRowFormula(rows, data) {
        let sourceData = await this.context.getCpasTableGrid();
        if (data) {
            sourceData["data"] = data;
        }
        try {
            const res = await refreshPolymericRowFormulaAPI(rows, sourceData);
            if (res?.data) {
                await this.context.reloadTable(res.data, null, null, true);
            }
        }
        catch (e) {
            throw e;
        }
    }
    /**
     * 获取聚合行的聚合信息
     * @param row
     */
    getPolymerizationInfoByRow(row) {
        const gridData = this.context.data;
        const info = gridData[row][this.headerService.lastHeader];
        if (info) {
            return JSON.parse(info)["r_polymeric"];
        }
        return null;
    }
    /**
     * 获取自定义权重运算信息
     * @param row
     */
    getCustomWeightInfoByRow(row) {
        const gridData = this.context.data;
        const info = gridData[row][this.headerService.lastHeader];
        if (info) {
            return JSON.parse(info)["cw"];
        }
        return null;
    }
    //获取行聚合公式配置信息
    getRowPolymericToRowConfig(row) {
        const gridData = this.context.data;
        const rowData = gridData[row];
        const strConfig = rowData[this.headerService.lastHeader];
        let _config;
        if (strConfig) {
            _config = JSON.parse(rowData[this.headerService.lastHeader]);
        }
        return _config.r_polymeric;
    }
    /**
     * 设置聚合行的配置
     * @param row
     * @param param
     */
    async setRowPolymericToRowConfig(row, param) {
        const cellsMeta = this.hot.getCellsMeta();
        const gridData = this.context.data;
        const tagType = param?.tagType ? param?.tagType : "";
        for (let i = 0; i < cellsMeta.length; i++) {
            const cellMeta = cellsMeta[i];
            if (cellMeta.row === row) {
                const config = gridData[row][this.headerService.lastHeader];
                if (config) {
                    let _config = JSON.parse(config);
                    _config.r_polymeric = param;
                    gridData[row][this.headerService.lastHeader] =
                        JSON.stringify(_config);
                    break;
                }
            }
        }
        //自动设置cmap
        const val = tagType === "top"
            ? `行|聚合|合计|${parseInt(String(10000 * Math.random())) + ""}`
            : `行|标签聚合|合计|${parseInt(String(10000 * Math.random())) + ""}`;
        await this.hot.setDataAtCell(row, 0, val);
        await this.hot.updateData(gridData);
        let data = gridData.slice(0);
        if (val) {
            data[row][0] = val;
        }
        return data;
    }
    /**
     * 设置/删除行运算符的配置
     * @param row
     * @param param
     */
    async setRowOperatorToRowConfig(row, param, type) {
        const cellsMeta = this.hot.getCellsMeta();
        const gridData = this.context.data;
        for (let i = 0; i < cellsMeta.length; i++) {
            const cellMeta = cellsMeta[i];
            if (cellMeta.row === row) {
                const config = gridData[row][this.headerService.lastHeader];
                if (config) {
                    let _config = JSON.parse(config);
                    //删除行运算符标记
                    _config.operator_r = param;
                    gridData[row][this.headerService.lastHeader] =
                        JSON.stringify(_config);
                    break;
                }
            }
        }
        this.hot.updateData(gridData);
    }
    /**
     * 设置聚合列的配置
     * @param column
     * @param param
     */
    setColumnPolymericToColumnConfig(column, param) {
        const tagType = param?.tagType ? param?.tagType : "";
        console.log(tagType, "tagType---", param);
        const update_config_headerJson = this.headerService.updateHeaderConfigByIndex(this.headerService.headJson, column, param);
        const val = tagType === "left"
            ? `列|聚合|合计|${parseInt(String(10000 * Math.random())) + ""}`
            : `列|标签聚合|合计|${parseInt(String(10000 * Math.random())) + ""}`;
        //自动设置cmap
        this.hot.setDataAtCell(0, column, val);
        this.headerService.headerCompute(update_config_headerJson);
        const gridData = this.context.data;
        this.hot.updateData(gridData);
        let data = gridData.slice(0);
        if (val) {
            data[0][column] = val;
        }
        return data;
    }
    /**
     * 返回所有聚合列的列号
     */
    getAllPolymericColumn() {
        const col = [];
        const headerData = this.headerService.headerColumn;
        for (let i = 0; i < headerData.length; i++) {
            const header = headerData[i];
            if (header.config && header.config.c_polymeric) {
                col.push(i);
            }
        }
        return col;
    }
    /**
     * 刷新所有聚合列的公式 @todo 已迁移后端，后续删除
     */
    async refreshAllPolymericColumn() {
        const polymericColumn = this.getAllPolymericColumn();
        if (!polymericColumn.length) {
            return;
        }
        //todo 精准更新 polymericColumn 只更新和该标签相关的聚合列
        this.refreshPolymericColumnFormula(polymericColumn);
        // for (let i = 0; i < polymericColumn.length; i++) {
        //   const item = polymericColumn[i];
        //   this.refreshPolymericColumnFormula(item);
        // }
    }
    /**
     * 刷新聚合列公式 @todo 已迁移后端，后续删除
     * @param row
     */
    async refreshPolymericColumnFormula(cols) {
        /*const sourceData = this.context.getCpasTableGrid();
        try {
          const iGridData = await refreshPolymericColumnFormulaAPI(cols, sourceData);
          console.log(iGridData?.data?.sourceData, 'iGridData111111');
          if(iGridData?.data?.sourceData) {
            this.context.reloadTable(iGridData?.data?.sourceData);
          }
        }catch(e) {
          throw e;
        }*/
        const cellsMeta = this.hot.getCellsMeta();
        const insert_param = [];
        //获取聚合行列数据引用
        for (let j = 0; j < cols.length; j++) {
            const col = cols[j];
            const c_polymericInfo = this.getColumnPolymericToColumnConfig(col);
            if (!c_polymericInfo) {
                console.error("未获取到c_polymericInfo");
                return;
            }
            const colData = this.hot.getDataAtCol(col);
            for (let i = 0; i < colData.length; i++) {
                const matchCellMeta = this.gridService.getCellMateDataByRowAndProp(i, col, cellsMeta);
                // const matchCellMeta = this.hot.getCellMeta(i,col)
                if (matchCellMeta && matchCellMeta.type === "numeric") {
                    let formula = [];
                    const matchCellMeta = this.conditionMatchTagValue(c_polymericInfo.tags, "column");
                    for (let j = 0; j < matchCellMeta.length; j++) {
                        const cellMeta = matchCellMeta[j];
                        if (cellMeta && cellMeta.type === "numeric") {
                            //如果匹配到的单元格元信息和该行所属于同一列，则进行坐标拼接
                            if (cellMeta.row === i) {
                                formula.push(`${createCellPos(cellMeta.col)}${cellMeta.row + 1 + startOffset}`);
                            }
                        }
                    }
                    // const formula = `${wordArray[col + 1]}${row + 1}`
                    // [[row, col, value],...]
                    const cType = c_polymericInfo.type;
                    const result = cType === "CLEAR" ? "" : `=${cType}(${formula.join(",")})`;
                    const insert_param_item = [i, col, result];
                    insert_param.push(insert_param_item);
                }
            }
        }
        console.log(insert_param, "insert_param111");
        this.hyper.rebuildAndRecalculate();
        this.hot.setDataAtCell(insert_param);
    }
    /**
     * 刷新所有聚合行公式 @todo 已迁移后端，后续删除
     */
    refreshAllPolymericRow() {
        //获取所有聚合行索引号
        const polymericRow = this.getAllPolymericRow();
        if (!polymericRow.length) {
            return;
        }
        //todo 精准更新 polymericRow 只更新和该标签相关的聚合行
        this.refreshPolymericRowFormula(polymericRow);
        // for (let i = 0; i < polymericRow.length; i++) {
        //   const item = polymericRow[i];
        //   //循环刷新单个聚合行公式
        //   this.refreshPolymericRowFormula(item);
        // }
    }
    /**
     * 刷新聚合行公式 @todo 已迁移后端，后续删除
     * @param row  如果传row 则刷新指定行的公式.  如果没传则自动检测所有聚合行进行公式刷新 (重新获取tag数据进行公式计算)
     */
    refreshPolymericRowFormula(rows) {
        const gridData = this.context.data;
        const currentCellMeta = this.hot.getCellsMeta();
        const insert_param = [];
        for (let k = 0; k < rows.length; k++) {
            const row = rows[k];
            //获取聚合行数据
            let rowData = gridData[row];
            //获取聚合行上一次的公式
            const polymericInfo = this.getRowPolymericToRowConfig(row);
            if (!polymericInfo) {
                console.error("未获取到polymericInfo");
                return;
            }
            for (let i = 0; i < rowData.length; i++) {
                //获取单元格的元信息
                const matchCellMeta = this.gridService.getCellMateDataByRowAndProp(row, i, currentCellMeta);
                //只有元信息为数字类型才参与运算
                if (matchCellMeta && matchCellMeta.type === "numeric") {
                    let formula = [];
                    //匹配到所有的tag标签的单元格元信息
                    const matchCellMeta = this.conditionMatchTagValue(polymericInfo.tags, "row");
                    for (let j = 0; j < matchCellMeta.length; j++) {
                        const cellMeta = matchCellMeta[j];
                        //如果匹配到的单元格元信息和该行所属于同一列，则进行坐标拼接
                        if (cellMeta.col === i) {
                            if (cellMeta.w) {
                                //加入行的权重计算,减操作是-1，中的操作是排除当前行
                                if (cellMeta.w === "j") {
                                    formula.push(`${createCellPos(cellMeta.col)}${cellMeta.row + 1 + startOffset}*-1`);
                                }
                                /*formula.push(
                                  `${createCellPos(cellMeta.col)}${
                                    cellMeta.row + 1 + startOffset
                                  }*${cellMeta.w === "z" ? 0 : -1}`
                                );*/
                            }
                            else {
                                formula.push(`${createCellPos(cellMeta.col)}${cellMeta.row + 1 + startOffset}`);
                            }
                        }
                    }
                    // const formula = `${wordArray[col + 1]}${row + 1}`
                    const rType = polymericInfo.type;
                    const result = rType === "CLEAR" ? "" : `=${rType}(${formula.join(",")})`;
                    const insert_param_item = [row, i, result];
                    insert_param.push(insert_param_item);
                }
            }
        }
        console.log(insert_param, "insert_param111");
        //遍历选中行的数据
        this.hyper.rebuildAndRecalculate();
        this.hot.setDataAtCell(insert_param);
    }
    /**
     * 返回所有聚合行的行号
     */
    getAllPolymericRow() {
        const row = [];
        const gridData = this.context.data;
        for (let i = 0; i < gridData.length; i++) {
            const rowData = gridData[i];
            const configStr = rowData[this.headerService.lastHeader];
            if (configStr && configStr?.search("r_polymeric") > -1) {
                row.push(i);
            }
        }
        return row;
    }
    getColumnPolymericToColumnConfig(col) {
        const columnConfig = this.headerService.getHeaderConfigByIndex(this.headerService.headJson, col).config;
        return columnConfig.c_polymeric || null;
    }
    conditionMatchTagValue(tags, type) {
        if (!this.hot) {
            return [];
        }
        let a_meta = [];
        const currentCellMeta = this.hot.getCellsMeta();
        // const gridData = hotRef.current.getData();
        for (let i = 0; i < currentCellMeta.length; i++) {
            const cellMeta = currentCellMeta[i];
            if (!cellMeta) {
                continue;
            }
            const { row, col } = cellMeta;
            if (type === "row" && cellMeta.r_tag) {
                const result = cellMeta.r_tag.findIndex((item) => tags.includes(item));
                if (result > -1) {
                    a_meta.push(cellMeta);
                }
            }
            if (type === "column" && cellMeta.c_tag) {
                const result = cellMeta.c_tag.findIndex((item) => tags.includes(item));
                if (result > -1) {
                    a_meta.push(cellMeta);
                }
            }
        }
        return a_meta;
    }
}
